﻿namespace NKernel.Core.Impl
{
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// Provides synchronized access to the kernel
    /// </summary>
    internal class SynchronizedKernelDecorator : IKernel
    {
        #region Fields

        private static readonly object LockObject = new Object();

        private readonly IKernel kernel;

        #endregion Fields

        #region Constructors

        public SynchronizedKernelDecorator(IKernel kernel)
        {
            this.kernel = kernel;
        }

        #endregion Constructors

        #region Methods

        public KernelResult Cleanup()
        {
            lock (LockObject)
            {
                return kernel.Cleanup();
            }
        }

        public IList<IComponentObject> GetComponents()
        {
            lock (LockObject)
            {
                return kernel.GetComponents();
            }
        }

        public T GetInstance<T>()
        {
            return kernel.GetInstance<T>();
        }

        public KernelResult Init()
        {
            lock (LockObject)
            {
                return kernel.Init();
            }
        }

        public void InitPriorityList(string[] components)
        {
            lock (LockObject)
            {
                kernel.InitPriorityList(components);
            }
        }

        public KernelResult Load(string[] componentLocations)
        {
            lock (LockObject)
            {
                return kernel.Load(componentLocations);
            }
        }

        public KernelResult Load()
        {
            return kernel.Load();
        }

        public KernelResult Manage()
        {
            return kernel.Manage();
        }

        public KernelResult Manage(string[] componentLocations)
        {
            lock (LockObject)
            {
                return kernel.Manage(componentLocations);
            }
        }

        public KernelResult Start()
        {
            lock (LockObject)
            {
                return kernel.Start();
            }
        }

        public KernelResult Stop()
        {
            lock (LockObject)
            {
                return kernel.Stop();
            }
        }

        #endregion Methods
    }
}